package com.voice.server.channel;

import com.voice.core.utils.ResponseUtil;
import com.voice.core.DefaultClient;
import com.voice.core.entity.HttpHeader;
import com.voice.core.ResponseCodeEnum;
import com.voice.core.connection.Connection;
import com.voice.core.connection.callback.AbstractStreamListener;
import com.voice.core.connection.entity.Stream;
import com.voice.core.connection.entity.StreamData;
import com.voice.server.auth.Authorization;
import com.voice.server.channel.handle.StreamListenerHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class DefaultStreamListener extends AbstractStreamListener {

    @Autowired
    private Map<String, Authorization> authorizationMap;
    @Autowired
    private Map<String,StreamListenerHandler> streamListenerHandlerMap;
    @Autowired
    private DefaultClient defaultClient;

    @Override
    public void onHeadersRead(Connection connection, Stream stream, HttpHeader requestHeader, boolean endOfStream) {
        String name=requestHeader.get("name",String.class);
        Authorization authorization=authorizationMap.get(name);
        String userId;
        if(authorization==null||(userId=authorization.authorization(requestHeader))==null){
            this.defaultClient.sendResponse(connection, stream.getStreamId(), ResponseUtil.error(ResponseCodeEnum.Unauthorized), ()->connection.close());
        }else{
            requestHeader.put("userId",userId);
            StreamListenerHandler streamListenerHandler= streamListenerHandlerMap.get(requestHeader.path());
            if(streamListenerHandler==null) this.defaultClient.sendResponse(connection, stream.getStreamId(), ResponseUtil.error(ResponseCodeEnum.BadRequest), ()->connection.close());
            try {
                streamListenerHandler.handle(requestHeader,connection);
            } catch (Exception e) {
                this.defaultClient.sendResponse(connection, stream.getStreamId(), ResponseUtil.error(ResponseCodeEnum.ServiceUnavailable), ()->connection.close());
                return;
            }
            this.defaultClient.sendResponse(connection, stream.getStreamId(), ResponseUtil.success());
        }
    }

    @Override
    public void onDataRead(Connection connection, Stream stream, StreamData streamData) {}

}
